//! \file QueueList_TODO.h
//! \brief Defines the <code>fullsail_ai::data_structures::QueueList</code> class template
//! implementation.
//! \author Cromwell D. Enage
#ifndef _FULLSAIL_AI_FUNDAMENTALS_QUEUELIST_TODO_H_
#define _FULLSAIL_AI_FUNDAMENTALS_QUEUELIST_TODO_H_

namespace fullsail_ai { namespace fundamentals {

	//! \todo
	//!   - Complete the definition of the <code>QueueList::Iterator</code> pre-increment operator.
	//!   - Complete the definition of the <code>QueueList::Iterator</code> dereference operator.
	//!   - Define the <code>QueueList</code> constructor.
	//!   - Define the <code>QueueList</code> destructor.
	//!   - Define the <code>QueueList</code> methods.
	template <typename T>
	void QueueList<T>::enqueue(T element)
	{
		Node* nNode = new Node(element);
		nNode->data = element;
		nNode->next = NULL;
		if(isEmpty())
		{
			front = nNode;
			back = front;
			return;
		}
		else
		{
			back->next = nNode;
			back = nNode;
		}

	}
	template <typename T>
	bool QueueList<T>::contains(T element) const
	{
		Node *pCurr = front;
		while (pCurr != NULL)
		{
			if(pCurr->data == element)
				return true;
			else
				pCurr = pCurr->next;
		}
		return false;
	}
	template <typename T>
	void QueueList<T>::remove(T element)
	{
		Node *pCurr  = front;
		Node *pPrev = NULL;
		Node *pNext = front->next;

		while (pCurr != NULL)
		{
			if(pCurr->data == element)
			{

				if(pPrev)
					pPrev->next = pNext;
				else if(pCurr == front)				
					front = pNext;
				else if(pNext == NULL)
					back = pPrev;

				delete pCurr;
				pCurr = NULL;
				return;
			}
			pPrev = pCurr;
			pCurr = pCurr->next;
			if(pCurr == NULL)
				pNext = NULL;
			else
				pNext = pCurr->next;
		}
	}
	template <typename T>
	void QueueList<T>::dequeue()
	{
		Node* delnode = front;
		// Spec case only one
		front = front->next;
		if(delnode == back)
		{
			front = NULL;
			back = NULL;
		}
		delete delnode;
	}
	template <typename T>
	void QueueList<T>::removeAll()
	{
		while(front != NULL && back != NULL)
			dequeue();
	}
	template <typename T>
	typename QueueList<T>::Iterator& QueueList<T>::Iterator::operator++()
	{
		// TODO: Complete the definition of this operator.
		currentNode = currentNode->next;
		return *this;
	}

	template <typename T>
	T QueueList<T>::Iterator::operator*() const
	{
		// TODO: Complete the definition of this operator.
		return currentNode->data;
	}
	template <typename T>
	T QueueList<T>::getFront() const
	{
		return front->data;
	}

	template <typename T>
	bool QueueList<T>::isEmpty() const
	{
		if(front)
			return false;
		return true;
	}
	template <typename T>
	QueueList<T>::QueueList()
	{
		front = NULL;
		back = NULL;
	}
	template <typename T>
	QueueList<T>::~QueueList()
	{
		removeAll();
	}

}}  // namespace fullsail_ai::fundamentals

#endif  // _FULLSAIL_AI_FUNDAMENTALS_QUEUELIST_TODO_H_

